"""
交易相关模型
===========
定义交易系统相关的所有数据模型
"""

from typing import Optional
from datetime import datetime
from decimal import Decimal
from pydantic import Field, validator
from .base_model import BaseModel, UUIDMixin, TimestampMixin
from .enums import TradeType, OrderType, OrderStatus, MarketType


class TradeOrder(UUIDMixin, TimestampMixin):
    """交易订单"""
    
    user_id: str = Field(
        description="用户ID"
    )
    
    symbol: str = Field(
        description="交易对符号",
        example="BTCUSD"
    )
    
    market_type: MarketType = Field(
        description="市场类型"
    )
    
    order_type: OrderType = Field(
        description="订单类型"
    )
    
    trade_type: TradeType = Field(
        description="交易类型"
    )
    
    quantity: Decimal = Field(
        description="交易数量",
        gt=0,
        decimal_places=8
    )
    
    price: Optional[Decimal] = Field(
        default=None,
        description="价格（限价单需要）",
        gt=0,
        decimal_places=8
    )
    
    stop_price: Optional[Decimal] = Field(
        default=None,
        description="止损价格",
        gt=0,
        decimal_places=8
    )
    
    filled_quantity: Decimal = Field(
        default=Decimal('0'),
        description="已成交数量",
        ge=0,
        decimal_places=8
    )
    
    average_price: Optional[Decimal] = Field(
        default=None,
        description="平均成交价格",
        gt=0,
        decimal_places=8
    )
    
    status: OrderStatus = Field(
        default=OrderStatus.PENDING,
        description="订单状态"
    )
    
    expires_at: Optional[datetime] = Field(
        default=None,
        description="过期时间"
    )
    
    cancelled_at: Optional[datetime] = Field(
        default=None,
        description="取消时间"
    )
    
    @validator('price')
    def validate_price(cls, v, values):
        order_type = values.get('order_type')
        if order_type in [OrderType.LIMIT, OrderType.STOP_LIMIT] and v is None:
            raise ValueError(f'{order_type.value}订单必须指定价格')
        return v
    
    @property
    def remaining_quantity(self) -> Decimal:
        """剩余数量"""
        return self.quantity - self.filled_quantity
    
    @property
    def fill_percentage(self) -> float:
        """成交百分比"""
        if self.quantity == 0:
            return 0.0
        return float(self.filled_quantity / self.quantity * 100)
    
    @property
    def is_fully_filled(self) -> bool:
        """是否完全成交"""
        return self.filled_quantity >= self.quantity
    
    def calculate_total_value(self) -> Optional[Decimal]:
        """计算总价值"""
        if self.average_price is not None and self.filled_quantity > 0:
            return self.average_price * self.filled_quantity
        return None


class Trade(UUIDMixin, TimestampMixin):
    """成交记录"""
    
    order_id: str = Field(
        description="订单ID"
    )
    
    user_id: str = Field(
        description="用户ID"
    )
    
    symbol: str = Field(
        description="交易对符号"
    )
    
    trade_type: TradeType = Field(
        description="交易类型"
    )
    
    quantity: Decimal = Field(
        description="成交数量",
        gt=0,
        decimal_places=8
    )
    
    price: Decimal = Field(
        description="成交价格",
        gt=0,
        decimal_places=8
    )
    
    fee: Decimal = Field(
        default=Decimal('0'),
        description="手续费",
        ge=0,
        decimal_places=8
    )
    
    fee_currency: Optional[str] = Field(
        default=None,
        description="手续费币种"
    )
    
    @property
    def total_value(self) -> Decimal:
        """总价值"""
        return self.quantity * self.price
    
    @property
    def net_value(self) -> Decimal:
        """净价值（扣除手续费）"""
        return self.total_value - self.fee


class Position(UUIDMixin, TimestampMixin):
    """持仓"""
    
    user_id: str = Field(
        description="用户ID"
    )
    
    symbol: str = Field(
        description="交易对符号"
    )
    
    market_type: MarketType = Field(
        description="市场类型"
    )
    
    quantity: Decimal = Field(
        description="持仓数量",
        decimal_places=8
    )
    
    average_price: Decimal = Field(
        description="平均成本价",
        gt=0,
        decimal_places=8
    )
    
    current_price: Optional[Decimal] = Field(
        default=None,
        description="当前价格",
        gt=0,
        decimal_places=8
    )
    
    unrealized_pnl: Optional[Decimal] = Field(
        default=None,
        description="未实现盈亏",
        decimal_places=8
    )
    
    realized_pnl: Decimal = Field(
        default=Decimal('0'),
        description="已实现盈亏",
        decimal_places=8
    )
    
    @property
    def position_value(self) -> Decimal:
        """持仓价值"""
        return abs(self.quantity) * self.average_price
    
    @property
    def current_value(self) -> Optional[Decimal]:
        """当前价值"""
        if self.current_price is not None:
            return abs(self.quantity) * self.current_price
        return None
    
    @property
    def is_long(self) -> bool:
        """是否多头"""
        return self.quantity > 0
    
    @property
    def is_short(self) -> bool:
        """是否空头"""
        return self.quantity < 0
    
    def update_unrealized_pnl(self, current_price: Decimal):
        """更新未实现盈亏"""
        self.current_price = current_price
        if self.quantity > 0:  # 多头
            self.unrealized_pnl = self.quantity * (current_price - self.average_price)
        else:  # 空头
            self.unrealized_pnl = abs(self.quantity) * (self.average_price - current_price)


class TradeHistory(BaseModel):
    """交易历史查询"""
    
    user_id: str = Field(description="用户ID")
    symbol: Optional[str] = Field(default=None, description="交易对符号")
    trade_type: Optional[TradeType] = Field(default=None, description="交易类型")
    start_date: Optional[datetime] = Field(default=None, description="开始日期")
    end_date: Optional[datetime] = Field(default=None, description="结束日期")
    limit: int = Field(default=100, ge=1, le=1000, description="查询数量限制")
    offset: int = Field(default=0, ge=0, description="查询偏移量")
